// Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'

Shader "Custom/s8_specular"
{
    Properties
    {
        _Diffuse("Diffuse Color", Color) = (1, 1, 1, 1)
        is_use_lambert_diffuse("is_use_lambert_diffuse", Range(0,1)) = 1
        _Lambert_k("Coefficient k of Lambert", float) = 0.5

        _Gloss("Gloss", Range(5,200)) = 10
        _SpecularColor("Specular Color", Color) = (1, 1, 1, 1)
        
        is_use_fragment_specular("is_use_fragment_specular", Range(0,1)) = 1
        is_use_halfDir("is_use_halfDir", Range(0,1)) = 1
    }
    SubShader
    {
        Pass
        {
            Tags{ "LightMode"="ForwardBase" }
            
            CGPROGRAM
            
            fixed4 _Diffuse;
            fixed4 _SpecularColor;
            float _Lambert_k;
            fixed is_use_lambert_diffuse;
            fixed is_use_fragment_specular;
            fixed is_use_halfDir;
            half _Gloss;

            #include "Lighting.cginc"
            
            # pragma vertex vert
            # pragma fragment frag

            struct a2v
            {
                float4 vertex : POSITION;
                float3 normal : NORMAL;
                float4 textcoord : TEXCOORD0;
            };

            struct v2f
            {
                float4 position: SV_POSITION;
                float3 color: COLOR;
                float3 normal: TEXCOORD0;
                float4 vertex: TEXCOORD1;
            };

            fixed3 get_color(float4 vertex, fixed3 normalDir)
            {
                const fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.rgb;

                // const fixed3 lightDir = normalize(_WorldSpaceLightPos0.xyz);
                // const fixed3 lightDir = normalize(WorldSpaceLightDir(float4(vertex, 0)));
                const fixed3 lightDir = normalize(WorldSpaceLightDir(vertex));

                const float half_lambert = dot(normalDir, lightDir) * _Lambert_k + _Lambert_k;
                const float all_lambert = max(dot(normalDir, lightDir), 0);

                fixed3 diffuse;
                if (is_use_lambert_diffuse > 0.5)
                {
                    diffuse = _LightColor0.rgb * half_lambert * _Diffuse.rgb;
                }  
                else
                {
                    // 否则，使用_Color中定义的颜色
                    diffuse = _LightColor0.rgb * all_lambert * _Diffuse.rgb;
                }  
                
                const fixed3 reflectDir = normalize(reflect(-lightDir, normalDir));

                // --- [camera pos in word] - [vertex pos in word]
                // const fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz - mul(vertex, unity_WorldToObject));
                const fixed3 viewDir = normalize(UnityWorldSpaceViewDir(vertex));

                float cos_theta ;
                if (is_use_halfDir > 0.5)
                {
                    const fixed3 halfDir = normalize((viewDir + lightDir) / 2);
                    cos_theta = dot(normalDir, halfDir);
                }
                else
                {
                    cos_theta = dot(reflectDir, viewDir);
                }
                
                const fixed3 specular = _LightColor0.rgb * _SpecularColor * pow(max(cos_theta, 0), _Gloss);

                fixed3 color = diffuse + ambient + specular;
                return color;
            }

            v2f vert(a2v v)
            {
                v2f f;
                f.position = UnityObjectToClipPos(v.vertex);

                f.normal = v.normal;
                f.vertex = v.vertex;
                
                if (is_use_fragment_specular > 0.5)
                {
                    f.color = fixed3(1, 1, 1);
                }
                else
                {
                    const fixed3 normalDir = mul(v.normal, (float3x3)unity_WorldToObject);
                    f.color = get_color(v.vertex, normalDir);
                }
                return f;
            }

            float4 frag(v2f f) : SV_Target{
                if (is_use_fragment_specular > 0.5)
                {
                    fixed3 normalDir = mul(f.normal, (float3x3)unity_WorldToObject);
                    f.color = get_color(f.vertex, normalDir);
                    return fixed4(f.color, 1);
                }
                else
                {
                    return fixed4(f.color, 1);
                    return fixed4(1, 0, 0, 1);
                }
            }
            
            ENDCG
        }
    }
    FallBack "Diffuse"
}
